'''
    DATAPACKET STATUS:
    AFP - AVAILABLE FOR PROCESSING
    FIN - FINISHED

    MESSAGE STATUS:
    OK - RESPONSE
    INT - INTERUPTED
'''

from scopt.util import misc


def in_data_packet(raw_request):
    return {'id': misc.unique_id(),
            'status': 'AFP',
            'message': {'raw_request': raw_request}}


def out_data_packet():
    return {'id': '',
            'message': {'raw_response': ''}}


def exception(data_packet, error_code, text=None):
    text = _(error_code) if text is None else text
    data_packet['status'] = 'FIN'
    response = {'resh': {'status': 'INT'},
                'resd': {'reason': 'EXCEPTION',
                         'code': error_code,
                         'text': text}}
    data_packet['message']['response'] = response
    return data_packet


def validation_exception(data_packet, error_list):
    data_packet['status'] = 'FIN'
    response = {'resh': {'status': 'INT'},
                'resd': {'reason': 'VALIDATION',
                         'errors': error_list}}
    data_packet['message']['response'] = response
    return data_packet


def get_message_type(data_packet):
    return data_packet['message']['request']['reqh']['type']


def get_message_version(data_packet):
    return data_packet['message']['request']['reqh']['version']


def get_handler_id(data_packet):
    msg_t = get_message_type(data_packet)
    msg_v = get_message_version(data_packet)
    return msg_t + '.' + msg_v


def get_message_status(data_packet):
    return data_packet['message']['response']['resh']['status']


def set_message_status(data_packet, status):
    data_packet['message']['response']['resh']['status'] = status
    return data_packet


def get_tenant_id(data_packet):
    return data_packet['message']['request']['reqh']['tenant_id']


def set_tenant_id(data_packet, tenant_id):
    data_packet['message']['request']['reqh']['tenant_id'] = tenant_id
    return data_packet


def get_request(data_packet):
    return data_packet['message']['request']


def get_request_header(data_packet):
    return data_packet['message']['request']['reqh']


def get_request_data(data_packet):
    return data_packet['message']['request']['reqd']


def set_request(data_packet, request_data):
    data_packet['message']['request'] = request_data
    return data_packet


def get_response(data_packet):
    return data_packet['message']['response']


def set_response(data_packet, response):
    data_packet['message']['response'] = response
    return data_packet


def get_response_data(data_packet):
    return data_packet['message']['response']['resd']


def get_raw_request(data_packet):
    return data_packet['message']['raw_request']


def set_raw_request(data_packet, raw_request):
    data_packet['message']['raw_request'] = raw_request
    return data_packet


def get_raw_response(data_packet):
    return data_packet['message']['raw_response']


def set_raw_response(data_packet, raw_response):
    data_packet['message']['raw_response'] = raw_response
    return data_packet


def get_message_id(data_packet):
    return data_packet['id']


def get_security_token(data_packet):
    if 'security' not in data_packet['message']['request']['reqh']:
        return None

    return data_packet['message']['request']['reqh']['security']


def set_security_token(data_packet, token):
    data_packet['message']['request']['reqh']['security'] = token
    return data_packet


def set_username(data_packet, username):
    data_packet['security']['username'] = username
    return data_packet


def get_username(data_packet):
    return data_packet['security']['username']


def get_db(data_packet):
    return data_packet['context']['business']['db']


def set_db(data_packet, db):
    data_packet['context'] = {'business': {'db': db}}
    return data_packet


def finish_data_packet(data_packet):
    data_packet['status'] = 'FIN'
    return data_packet


def ok_response(data_packet, handler, resd=None):
    response = handler.RESPONSE()
    response['resd'] = resd
    response['resh']['status'] = 'OK'
    return set_response(data_packet, response)


def update_response(data_packet, result, handler):
    if result is not None:
        return exception(data_packet, result[1], result[2])
    else:
        return ok_response(data_packet, handler)


def delete_response(data_packet, result, handler):
    return update_response(data_packet, result, handler)


def insert_response(data_packet, result, handler, resd=None):
    if result_is_error(result):
        return exception(data_packet, result[1], result[2])
    else:
        return ok_response(data_packet, handler, resd)


def result_is_error(result):
    return isinstance(result, tuple) and result[0] == 'ERROR'
